#include "Protocol.hpp"
#include "Socket.hpp"

void Usage(std::string proc)
{
    std::cout << "\r\nUsage:" << proc << " Serverport Serverip" << std::endl;
}

int main(int argc, char *argv[])
{
    srand((unsigned)time(0) ^ getpid());

    // ./ServerCal Serverport Serverip
    if (argc != 3)
    {
        Usage(argv[0]);
        exit(0);
    }

    uint16_t Serverport = std::stoi(argv[1]);
    std::string Serverip = argv[2];

    Sock sk;
    sk.Socket();
    sk.Connect(Serverip, Serverport);

    std::string oper = "+-*/%~@=";
    int cnt = 1;
    while (cnt <= 10)
    {
        std::cout << "===========第" << cnt << "测试===========" << std::endl;
        int x = rand() % 10;
        int y = rand() % 10 + 1;
        char op = oper[rand() % (oper.size())];

        Request req(x, y, op);
        std::string package;
        req.serialize(&package);
        std::string content;
        Encode(package, &content);

        write(sk.Getfd(), content.c_str(), content.size());
        std::cout << "write success" << std::endl;

        char inbuffer[1024];
        std::string inbuffer_stream;
        int n = read(sk.Getfd(), inbuffer, sizeof(inbuffer));
        std::cout << "read success" << std::endl;

        if(n > 0)
        {
            inbuffer[n] = 0;
            inbuffer_stream += inbuffer;

            Response rsp;
            std::string content;
            Decode(inbuffer_stream, &content);
            rsp.Deserialize(content);

            rsp.Print();
        }
        else if(n = 0)
        {
            std::cout<< "n = 0" <<std::endl;
        }
        else
        {
            std::cout<< "n < 0" <<std::endl;
        }

        std::cout << "=================================" << std::endl;
        cnt++;
        sleep(1);
    }

    return 0;
}

// #include <iostream>
// #include <string>
// #include <ctime>
// #include <cassert>
// #include <unistd.h>
// #include "Socket.hpp"
// #include "Protocol.hpp"

// static void Usage(const std::string &proc)
// {
//     std::cout << "\nUsage: " << proc << " serverip serverport\n"
//               << std::endl;
// }

// // ./clientcal ip port
// int main(int argc, char *argv[])
// {
//     if (argc != 3)
//     {
//         Usage(argv[0]);
//         exit(0);
//     }
//     std::string serverip = argv[1];
//     uint16_t serverport = std::stoi(argv[2]);

//     Sock sockfd;
//     sockfd.Socket();
//     bool r = sockfd.Connect(serverip, serverport);
//     if(!r) return 1;

//     srand(time(nullptr) ^ getpid());
//     int cnt = 1;
//     const std::string opers = "+-*/%=-=&^";

//     std::string inbuffer_stream;
//     while(cnt <= 10)
//     {
//         std::cout << "===============第" << cnt << "次测试....., " << "===============" << std::endl;
//         int x = rand() % 100 + 1;
//         usleep(1234);
//         int y = rand() % 100;
//         usleep(4321);
//         char oper = opers[rand()%opers.size()];
//         Request req(x, y, oper);
//         req.Print();

//         std::string package;
//         req.serialize(&package);
//         std::string content;

//         Encode(package, &content);

//         write(sockfd.Getfd(), package.c_str(), package.size());
//         // std::cout << "这是最新的发出去的请求: " << n << "\n" << package;
//         // n = write(sockfd.Fd(), package.c_str(), package.size());
//         // std::cout << "这是最新的发出去的请求: \n" << n << "\n" << package;
//         // n = write(sockfd.Fd(), package.c_str(), package.size());
//         // std::cout << "这是最新的发出去的请求: \n" << n << "\n" << package;
//         // n = write(sockfd.Fd(), package.c_str(), package.size());
//         // std::cout << "这是最新的发出去的请求: \n" << n << "\n" << package;


//         char buffer[128];
//         ssize_t n = read(sockfd.Getfd(), buffer, sizeof(buffer)); // 我们也无法保证我们能读到一个完整的报文
//         if(n > 0)
//         {
//             buffer[n] = 0;
//             inbuffer_stream += buffer; // "len"\n"result code"\n
//             std::cout << inbuffer_stream << std::endl;
//             std::string content;
//             bool r = Decode(inbuffer_stream); // "result code"
//             assert(r);

//             Response resp;
//             r = resp.Deserialize(inbuffer_stream);
//             assert(r);

//             resp.Print();
//         }

//         std::cout << "=================================================" << std::endl;
//         sleep(1);

//         cnt++;
//     }


//     sockfd.Close();
//     return 0;
// }